<?php
if (PHP_VERSION < '5.0.0')
{
	throw new Exception('PHP 5.0 required!');
}

/**
 * 定义框架版本
 *
 */
define('NPHP_VERSION', '0.0.001');
/**
 * 缩写目录分隔符
 *
 */
define('DS', DIRECTORY_SEPARATOR);

/**
 * 定义框架根目录
 *
 */
define('ND_ROOT', dirname(__FILE__).DS);

/**
 * class separator
 *
 */
define('CS', '_');

define('URL_STANDARD', 'URL_STANDARD');

define('URL_PATHINFO', 'URL_PATHINFO');

define('URL_REWRITE', 'URL_REWRITE');

include_once('Functions.php');

/**
 * 设置异常处理函数
 */
set_exception_handler('ExceptionHandle');

class N {
	/**
	 * 配置文件数组
	 *
	 * @var array
	 */
	static private $_ini = array();
	
	/**
	 * 框架是否已经初始化
	 *
	 * @var bool
	 */
	static private $_hasInit = false;
	
	/**
	 * 用于保存全局变量,形式为 $id => $value
	 *
	 * @var array
	 */
	static private $_registery = array();
	
	static private $_pathInclude = array('.');
	
	/**
	 * 初始化框架
	 *
	 * @return null
	 */
	static public function init() 
	{
		if (self::$_hasInit) 
		{
			return;
		}
		self::$_hasInit = true;
		
		self::loadIni('Config/IniMapping.php');
		
		if (N::getIni('DEBUG'))
		{
			error_reporting(E_ALL |~ E_NOTICE);
		}
		else 
		{
			error_reporting(0);
		}
		
		self::_autoSession();
		self::_autoMagic();
		self::_autoOb();
	}
	
	/**
	 * 设置文件包含目录
	 *
	 * @param string $dirname
	 */
	static public function import($dirname)
	{
		$dirname = str_replace('\\', '/', $dirname);
		$dirname = rtrim($dirname, '/');
		$dirname = realpath($dirname);
		array_push(self::$_pathInclude, $dirname);
		set_include_path(get_include_path().';'.$dirname);
	}
	
	/**
	 * 载入配置文件,如果配置有重复则以最后一次导入的配置为准
	 *
	 * @param mixed $input
	 */
	static public function loadIni($input)
	{
		$args = func_get_args();
		$numOfArgs = sizeof($args);
		if ($numOfArgs === 2)
		//导入的配置是采用 名称/值 对的形式
		{
			$index = $args[0];
			$value = $args[1];
			if (is_array($index) && is_array($value))
			{
				$tmpArr = array_combine($index, $value);
				self::$_ini = $tmpArr + self::$_ini;
			}
			else if (is_string($index) && is_string($value))
			{
				self::$_ini = array_merge(self::$_ini, array($index=>$value));
			}
		}
		else if ($numOfArgs === 1)
		{
			$value = $args[0];
			if (is_array($value))
			{
				self::$_ini = $value + self::$_ini;
			}
			else
			//如果是文件路径 
			{
				if (file_exists(ND_ROOT.$value) && is_readable(ND_ROOT.$value))
				{
					$tmpArr = require_once(ND_ROOT.$value);
					self::$_ini = $tmpArr + self::$_ini;
				}
				else 
				{
					throw new Exception("File:$value could not read!");
				}
			}
		}
	}
	
	/**
	 * 获取某项配置
	 *
	 * @param string $index
	 * @return mixed
	 */
	static public function getIni($index)
	{
		return self::$_ini[$index];
	}
	
	static public function loadClass($className)
	{
		if (class_exists($className, false) || interface_exists($className, false))
		{//已经加载则直接返回
			return true;
		}
		$classPath = str_replace(CS, '/', $className).'.php';
		foreach (self::$_pathInclude as $path)
		{
			if (file_exists($path.'/'.$classPath))
			{
				include($path.'/'.$classPath);
			}
		}
		
		if (!(class_exists($className, false) || interface_exists($className, false)))
		{
			throw new Exception('Class file not exists!Class Name:'.$className);
		}
	}
	
	/**
	 * 是否自动开启session，如果需要对session做详细控制，请在将AUTO_START_SESSION
	 * 配置项置为false
	 *
	 */
	static private function _autoSession()
	{
		self::getIni('AUTO_START_SESSION') ? session_start() : null;
	}
	
	/**
	 * 是否打开输出缓冲
	 *
	 */
	static private function _autoOb()
	{
		if (self::getIni('AUTO_START_OB') && self::getIni('ENALBE_GZIP'))
		{
			ob_start("ob_gzhandler");
		}
		else if (self::getIni('AUTO_START_OB'))
		{
			ob_start();
		}
	}
	
	/**
	 * 自动转义处理
	 *
	 */
	static private function _autoMagic()
	{
		set_magic_quotes_runtime(0);
		//注销所有自动注册变量
		if (@ini_get('register_globals'))
		{
			foreach ($_REQUEST as $varName => $void)
			{
				unset(${$varName});
			}
		}
		//转义
		if (!get_magic_quotes_gpc())
		{
			adds($_GET);
			adds($_POST);
			adds($_COOKIE);
		}
	}
	
	//运行MVC框架
	static public function runMVC() 
	{
		$dispatcherClassName = self::getIni('DISPATCHER_CLASS_NAME');
		$dispatcher = N::getSingleton($dispatcherClassName);
		$dispatcher->dispatching();
	}
	
	/**
	 * 返回一个类的唯一全局实例
	 *
	 * @param string $id
	 * @param array $param
	 * @return Object
	 */
	static public function getSingleton($id, array $param = array())
	{
		if (!array_key_exists(md5($id), self::$_registery))
		{
			N::loadClass($id);
			$newObj = new $id($param);
			self::$_registery = array_merge(array(md5($id) => $newObj), self::$_registery);
			return $newObj;
		}
		return (self::$_registery[md5($id)]);
	}
}